Repository navigation
Conversation
`setup` read INITIAL_PASSWORD unconditionally and re-hashed it over whatever was already stored. A default npm install has INITIAL_PASSWORD=CHANGEME in the environment, so any later `setup` run -- including one that only meant to add a provider -- silently replaced the operator's own password with the well-known default, while printing "Admin password configured". The server already treats the env var as a seed rather than an override: `storedPassword || getInitialPasswordValue(...)` in src/lib/auth/managementPassword.ts. The CLI now applies the same rule. An explicit --password still wins, and a first install with no stored password still seeds from the env var, which is what diegosouzapw#8439 added it for. Closes diegosouzapw#11494
|
Nine checks are red. All nine are the base, not this diff — and the five new tests pass in CI. The failing set is identical on unrelated PRs cut from the same base. #11496 and #11499 share none of this diff and fail exactly these nine: Unit Tests fast-path (1/4) — the five failures there are agent-card assertions: Nothing there reads the CLI or the settings store, and neither of this PR's test files appears in those logs. Build (advisory) is the What this PR's own tests did in CI — pulled from the shard logs rather than inferred: Every other Happy to rebase once the base is green. |
|
Superseded by #11522 — closing this rather than rebasing it. I went to rebase onto the new // a8dbf7bbb — fix(cli): preserve existing admin password during setup (#11522)
async function resolvePassword(opts, prompt, nonInteractive, settings) {
if (opts.password !== undefined) return opts.password;
if (!settings.password && process.env.INITIAL_PASSWORD) return process.env.INITIAL_PASSWORD;Same root cause, same rule — Their tests cover it too, including the case I thought was mine to add — Nothing here to salvage. Thanks to whoever picked it up — the fix is in the right place. |
Closes #11494.
omniroute setupreadINITIAL_PASSWORDunconditionally and re-hashed it over whatever was already stored. A defaultnpm install -g omniroutehas that variable in the environment carryingCHANGEME, so any latersetuprun — including one whose only purpose was--add-provider— silently replaced the operator's own password with the well-known default, and printed✔ Admin password configuredwhile doing it.Why the CLI is the odd one out
The server already treats the variable as a seed rather than an override —
src/lib/auth/managementPassword.ts:The stored hash wins there, and when the value is the well-known default the server logs a loud
[AUTH][SECURITY]warning. The CLI path added in #8439 had neither guard. This makes the two agree: one line inresolvePassword, gated on the password that is already stored.--passwordstill wins, and a first install with nothing stored still seeds from the environment — which is what #8439 added the read for.One behaviour change worth calling out
Interactively, with
INITIAL_PASSWORDset and a password already stored, the user now sees the existingSet an admin password now? [y/N]prompt instead of having the env var applied silently. AnsweringNleaves the stored password alone. Before this change that prompt was unreachable whenever the variable was set.I did not touch the packaging half of the report (an active
.envinside the published tarball).package.json'sfileslist ships.env.example, not.env, so whatever produces the installed.envis a separate question from this one, and this fix stands on its own either way:INITIAL_PASSWORDshould not overwrite a set password no matter how it got into the environment.Tests
Two layers, because they fail for different reasons.
tests/unit/cli/setup-initial-password-11494.test.ts(new, 4 assertions) — the decision alone, no database and no TTY.resolvePasswordis now exported for this, matching howmergeSetupOptionsis already exported and tested intests/unit/cli/setup-provider-api-key.test.ts. The injected prompt callsassert.fail, so a regression that starts prompting non-interactively fails loudly instead of hanging.tests/unit/cli-setup-command.test.ts(1 added) — the issue's reproduction end to end against a real SQLite file: set a password, runsetupagain with no--passwordwhileINITIAL_PASSWORD=CHANGEME, then assert the stored bcrypt hash still matches the operator's password and does not matchCHANGEME.Mutation-checked. Reverting the guard to the old unconditional
if (process.env.INITIAL_PASSWORD):INITIAL_PASSWORD does not replace a password that is already set;a later setup run does not re-seed INITIAL_PASSWORD over the stored password.The other three unit assertions pass under that mutation by design: they pin behaviour this PR preserves (
#8439seeding,--passwordprecedence, the non-interactive no-op), not the behaviour it changes.Commands run
Both pre-existing
INITIAL_PASSWORDtests incli-setup-command.test.tsstill pass unchanged: one seeds on a fresh data dir, where nothing is stored and the variable still applies; the other passes--password, which short-circuits ahead of the new condition.Full
npm run test:coveragewas not run locally — the changed lines are the fourresolvePasswordbranches plus thegetSettingshoist insetupPassword, all executed by the tests above.Local note, not a repo problem:
tests/unit/cli-setup-command.test.tsimportsbetter-sqlite3directly and the package was absent from my checkout, so I installed it withnpm i --no-saveto run that file.package.jsonandpackage-lock.jsonare untouched by this branch.